#!/bin/bash
#
# This shell script allows to install a distribution (mainly Mandriva) into an
# empty disk. Its real main purpose is to install a minimal Mandriva 
# distribution on an empty virtual disk for a given virtual machine engine. 
#
# Known bugs:
#
# * issue with network not going up
#

mnt_point="/mnt/part"
dir="/usr/share/mbootstrap" # install dir

device="/dev/sdb"
fs_type="ext3"

echo "This is mboostrap, installer of Linux on a new partition."
echo "Be careful, all the data in the device you will stipple will be lost !"
echo ""

# device selection
select_device()
{
   # all sd/hd devices
   all_dev=`ls /dev/sd* /dev/hd* | grep [^0-9*]$`

   # looking for unused devices
   av_dev=""

   for i in ${all_dev}
   do
      x=`cat /etc/mtab | grep ${i}`

      if [ "${x}" = "" ]
      then
	 av_dev="${av_dev} ${i}"
      fi
   done

   # the default device is the first unused device
   default_device=`echo ${av_dev} | awk '{print $1}'`

   echo -n "Select device (${av_dev}): "
   read device

   if [ "${device}" = "" ]
   then
      device="${default_device}"
   fi

   # check if the chosen device was in the list of available devices
   good=`echo ${av_dev} | grep ${device}`

   if [ "${good}" = "" ]
   then
      echo " Unknown device"

      echo -n " Are you sure of your choice ? (y/n) "
      read sure

      if [ "${sure}" = "y" ]
      then
	 echo " OK. Continuing."
      else
	 select_device
      fi
   fi

   echo " ${device} selected"

   dev_size=`sfdisk -s | grep ${device} | awk '{ print $2 }'`
   dev_size=$((${dev_size}/1024))

   echo " ${device} size is: ${dev_size} MB"
}

fill_device()
{
   echo "Filling device with zeros..."
   dd if=/dev/zero of=${device}
}

# filesystem selection
select_fs()
{
   av_fs=`ls /sbin/mkfs* | awk -F "." '{ print $2; }' | tr "\n" " "`
   echo -n "Select filesystem (${av_fs}): "
   read fs_type

   if [ "${fs_type}" = "" ]
   then
      fs_type="ext3"
   fi

   good=`echo ${av_fs} | grep ${fs_type}`

   if [ "${good}" = "" ]
   then
      echo "Unsupported filesystem"
      select_fs
   fi

   echo " ${fs_type} selected"
}

# partition creation
create_partition()
{
   echo "Creating partition table on ${device}..."
   parted ${device} mklabel msdos
   if [ $? -ne 0 ]
   then
      echo " Failed"
      exit 1
   fi
   sleep 2
   sync

   echo "Creating partition on ${device}..."
   parted ${device} mkpart primary 0 ${dev_size}
   sleep 2
   sync
   
   if [ $? -ne 0 ]
   then
      echo " Failed"
      exit 1
   fi

   echo " Done."
}

# partition formatting
format_partition()
{
   echo -n "Formatting ${device}1 with ${fs_type}..."

   mkfs.${fs_type} ${device}1

   if [ $? -ne 0 ]
   then
      echo " Failed"
      exit 1
   fi

   echo " Done."
}

# Partition mounting
mount_partition()
{
   echo -n "Mounting partition ${device}1 on ${mnt_point}..."
   mkdir ${mnt_point} 2> /dev/null
   mount -t ${fs_type} ${device}1 ${mnt_point}

   if [ $? -ne 0 ]
   then
      echo " Failed."
      exit 1
   fi

   echo " Done."
}

create_common_files()
{
   echo "Creating common files"
   # TODO: ensure this will be okay for any distro... and any vm type
   mkdir ${mnt_point}/etc 2> /dev/null
   echo "/dev/sda1 / ${fs_type} relatime 1 1" > ${mnt_point}/etc/fstab

   if [ -f ${mnt_point}/etc/resolv.conf ]
   then
      mv ${mnt_point}/etc/resolv.conf ${mnt_point}/etc/resolv.conf.backup
   fi

   cp /etc/resolv.conf ${mnt_point}/etc/resolv.conf
}

# Distribution choice
choose_distribution()
{
   list=`ls ${dir}/chroot`

   a=1
   for i in ${list}
   do
      echo "${a}: ${i}"
      eval cmd[${a}]=${i}
      a=$((${a}+1))
   done

   echo "q: Exit."
   echo ""
   echo -n "Choice: "

   read choice

   if [ "${choice}" = "q" ]
   then
      echo "Goodbye !"
      exit 0
   else
      echo "Running ${cmd[${choice}]} from ${mnt_point}"
      ${dir}/chroot/${cmd[${choice}]} ${mnt_point}

      if [ $? -ne 0 ]
      then
	 echo " Failed"
	 exit 1
      fi

      echo " Done."
      
      # adding the repository (rpm/deb sources)
      echo "Adding source list."
      cp ${dir}/repository/${cmd[${choice}]} ${mnt_point}/tmp/
      echo "chroot ${mnt_point} /tmp/${cmd[${choice}]}"
      chroot ${mnt_point} /tmp/${cmd[${choice}]}
      rm -f ${mnt_point}/tmp/${cmd[${choice}]}
   fi
}

install_grub()
{
   echo "Installing GRUB and initializing MBR..."
   grub-install --root-directory=${mnt_point} ${device}
   
   if [ $? -ne 0 ]
   then
      echo "Failed"
      exit 1
   else
      echo "Succeeded."
   fi
}

mount_vfs()
{
   mkdir ${mnt_point}/proc 2> /dev/null
   mkdir ${mnt_point}/sys 2> /dev/null
   mkdir ${mnt_point}/dev 2> /dev/null

   echo -n "Mounting /proc... "
   mount -o bind /proc ${mnt_point}/proc
   if [ $? -ne 0 ]
   then
      echo "Failed"
      exit 1
   else
      echo "Done."
   fi

   echo -n "Mounting /sys... "
   mount -o bind /sys ${mnt_point}/sys
   if [ $? -ne 0 ]
   then
      echo "Failed"
      exit 1
   else
      echo "Done."
   fi

   echo -n "Mounting /dev... "
   mount -o bind /dev ${mnt_point}/dev
   if [ $? -ne 0 ]
   then
      echo "Failed"
      exit 1
   else
      echo "Done."
   fi
}

create_initrd()
{
   echo "Please keep it mind that creating initrd does not ensure the system"
   echo "will work properly on your virtual machine depending on the simulated"
   echo "hardware on this virtual machine."
   echo ""

   echo "Creating initrd..."

   k_ver=`ls ${mnt_point}/lib/modules/`
   # | sed 's/.\{1\}$//g'` # this was to avoid the pending *
			   # but it seems it only appears under a tty
   echo " kernel version is ${k_ver}"
   chroot ${mnt_point} mkinitrd /boot/initrd.img ${k_ver}
   
   if [ $? -ne 0 ]
   then
      echo "Failed"
      exit 1
   else
      echo "Succeeded."
   fi
}

umount_vfs()
{
   echo -n "Unmounting /proc, /sys and /dev... "
   umount ${mnt_point}/proc
   umount ${mnt_point}/sys
   umount ${mnt_point}/dev
   echo " done."
}

end_install()
{
   echo "Finishing installation"

   if [ -f ${mnt_point}/etc/resolv.conf.backup ]
   then
      mv -f ${mnt_point}/etc/resolv.conf.backup ${mnt_point}/etc/resolv.conf
   fi

   echo "Unmounting ${mnt_point}"
   umount ${mnt_point}
}

install_post()
{
   echo -n "Do you want to install packages present in the post/ subdirectory (y/n) ?"
   read ans

   if [ "${ans}" = "n" ]; then
      echo " no post/ package installation"
   else
      echo "Installing all rpm present in ${dir}/post directory."
      tmp_dir=`mktemp -d ${mnt_point}/tmp/post_XXXX`
      cp ${dir}/post/* ${tmp_dir}

      only_dir=`echo ${tmp_dir} | awk -F "/" '{ print $NF }'`
   
      for i in ${tmp_dir}/*.rpm
      do
	 file=`echo ${i} | awk -F "/" ' { print $NF } '`
         echo "file= $file"
         echo "Running chroot ${mnt_point} rpm -ivh /tmp/${only_dir}/${file}"
	 chroot ${mnt_point} rpm -ivh /tmp/${only_dir}/${file}
      done

      rm -fr ${tmp_dir}
   fi
}

remove_net_udev_rules()
{
   echo -n "Deleting network udev rules for allowing any MAC addresses for any cards (Y/n) ? "
   read del_udev

   if [ "${del_udev}" != "n" ]; then
      echo "Deleting udev rules."
   
      if [ -f ${mnt_point}/etc/udev/rules.d/70-persistent-net.rules ]; then
	 rm -f ${mnt_point}/etc/udev/rules.d/70-persistent-net.rules
      else
         echo "udev rules have changed, please modify this script according to the changes:"
	 echo "file ${mnt_point}/etc/udev/rules.d/70-persistent-net.rules was not found"
      fi

      if [ -f ${mnt_point}/lib/udev/rules.d/75-persistent-net-generator.rules ]; then
	 rm -f ${mnt_point}/lib/udev/rules.d/75-persistent-net-generator.rules
      else
         echo "udev rules have changed, please modify this script according to the changes:"
	 echo "file ${mnt_point}/lib/udev/rules.d/75-persistent-net-generator.rules was not found"
      fi
   fi
}

select_device
fill_device
select_fs
create_partition
format_partition
mount_partition
mount_vfs
create_common_files
install_grub
choose_distribution
install_post
remove_net_udev_rules
umount_vfs
end_install

exit 0
